package cn.edu.xmu.orderpayment.order.mq.listener;

import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.orderpayment.order.dao.OrderDao;
import cn.edu.xmu.orderpayment.order.microservice.service.GoodsService;
import cn.edu.xmu.orderpayment.order.microservice.vo.QuantityVo;
import cn.edu.xmu.orderpayment.order.model.bo.Order;
import cn.edu.xmu.orderpayment.order.model.bo.OrderItem;
import cn.edu.xmu.orderpayment.order.model.enums.OrderState;
import cn.edu.xmu.orderpayment.order.model.po.OrderItemPo;
import cn.edu.xmu.privilegegateway.annotation.util.Common;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

/**
 * @author Yujie Lin
 * @date 2021/12/13 17:11
 */
@Service
@RocketMQMessageListener(topic = "order-pay-topic2", consumeMode = ConsumeMode.CONCURRENTLY, consumeThreadMax = 10, consumerGroup = "order-pay-group2")
public class OrderPayListener implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {
    private static final Logger logger = LoggerFactory.getLogger(OrderPayListener.class);

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private GoodsService goodsService;


    // 消费者获得支付成功信息，收到时进行分单，修改父订单状态为已分单，子订单为待发货（活动订单特殊处理）
    @Override
    public void onMessage(String documentId) {

        String orderSn = null;
        // 定金
        if (documentId.endsWith("-D")) {
            orderSn = documentId.substring(0, documentId.length() - 2);
            ReturnObject<Order> ret = orderDao.getOrderByOrderSn(orderSn);
            if (ret.getData() == null) return;
            Order order = ret.getData();
            if (order.getState() == OrderState.NEW_ORDER) {
                order.setState(OrderState.WAIT_REST);
                orderDao.updateOrder(order, order.getCreatorId(), order.getCreatorName());
            }
            return;
        }
        if (documentId.endsWith("-W")) {
            orderSn = documentId.substring(0, documentId.length() - 2);
            ReturnObject<Order> ret = orderDao.getOrderByOrderSn(orderSn);
            if (ret.getData() == null) return;
            Order order = ret.getData();
            if (order.getState() == OrderState.WAIT_REST) {
                order.setState(OrderState.HAS_PAYED);
                orderDao.updateOrder(order, order.getCreatorId(), order.getCreatorName());
            }
            return;
        }
        orderSn = documentId;
        ReturnObject ret = orderDao.getOrderByOrderSn(orderSn);
        if (ret.getData() == null) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ret = orderDao.getOrderByOrderSn(orderSn);
            if(ret.getData()==null)return;
        }
        Order order = cloneVo(ret.getData(),Order.class);

        if (order.getState() != OrderState.NEW_ORDER && order.getState() != OrderState.WAIT_REST) return;

        if (order.getGrouponId() != 0 && order.getState() == OrderState.NEW_ORDER) {
            order.setState(OrderState.WAIT_GROUP);
            orderDao.updateOrder(order, order.getCreatorId(), order.getCreatorName());
            return;
        }
        ReturnObject<List> itemsRet = orderDao.getOrderItemsByOrderId(order.getId());
        List<OrderItemPo> orderItemList = itemsRet.getData();

        Map<Long, List<OrderItemPo>> map = orderItemList.stream().collect(Collectors.groupingBy(OrderItemPo::getShopId));

        order.setState(OrderState.HAS_PAYED);

        // 无需分单
        if(map.size()==1){
            Set<Long> set=map.keySet();
            order.setShopId((Long) (set.toArray()[0]));
            orderDao.updateOrder(order, order.getCreatorId(), order.getCreatorName());
            return;
        }

        // 需要分单
        orderDao.updateOrder(order, order.getCreatorId(), order.getCreatorName());
        for (Map.Entry entry : map.entrySet()) {
            Order subOrder = cloneVo(order, Order.class);
            subOrder.init();
            subOrder.setShopId((Long) entry.getKey());
            subOrder.setPid(order.getId());
            subOrder.setState(OrderState.HAS_PAYED);
            Common.setPoCreatedFields(subOrder, order.getCreatorId(), order.getCreatorName());
            ReturnObject ret1 = orderDao.createOrder(subOrder);
            Order subOrder1 = cloneVo(ret1.getData(),Order.class);

            Long discountPrice = 0L;
            Long originPrice = 0L;
            Long point = 0L;

            for (OrderItemPo orderItem : (List<OrderItemPo>) entry.getValue()) {
                orderItem.setOrderId(subOrder1.getId());
                Common.setPoModifiedFields(orderItem, order.getCreatorId(), order.getCreatorName());
                orderDao.updateOrderItem(orderItem);
                originPrice += orderItem.getPrice()*orderItem.getQuantity();
                discountPrice += orderItem.getDiscountPrice()*orderItem.getQuantity();
                point += orderItem.getPoint();
            }
            subOrder1.setDiscountPrice(Math.round(1.0*discountPrice/10));
            subOrder1.setOriginPrice(originPrice);
            subOrder1.setPoint(point);
            orderDao.updateOrder(subOrder1, order.getCreatorId(), order.getCreatorName());

        }
        order.setState(OrderState.HAS_PAYED);
        orderDao.updateOrder(order, order.getCreatorId(), order.getCreatorName());

    }

    @Override
    public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
        logger.info("prepareStart: consumergroup =" + defaultMQPushConsumer.getConsumerGroup());
    }
}
